/* CsJni - .NET / Java Bridge
 * 
 * Copyright 2010 Robert E. Burke Licensed under the Apache License, Version 
 * 2.0 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
 * law or agreed to in writing, software distributed under the License is 
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
*/

using System;
using System.Collections.Generic;
using System.Text;

namespace CsJni
{
    #region JniVersion Enum

    public enum JniVersion : int
    {   // TODO - fix version number
        NoVersion = 0,
        Version1Minor2 = 0x00010002,
        Version1Minor4 = 0x00010004,
    }

    #endregion JniVersion Enum

    #region JniErrorCode Enum

    public enum JniErrorCode : int
    {
        [JniErrorCodeMeaning("jniErrorCodeOk")]
        Ok = 0,
        [JniErrorCodeMeaning("jniErrorCodeUnknownError")]
        UnknownError = (-1),
        [JniErrorCodeMeaning("jniErrorCodeDetached")]
        Detached = (-2),
        [JniErrorCodeMeaning("jniErrorCodeVersion")]
        Version = (-3),
        [JniErrorCodeMeaning("jniErrorCodeNoMemory")]
        NoMemory = (-4),
        [JniErrorCodeMeaning("jniErrorCodeExists")]
        Exists = (-5),
        [JniErrorCodeMeaning("jniErrorCodeInvalid")]
        Invalid = (-6),
    }

    #endregion JniErrorCode Enum

    #region JniErrorCodeMeaningAttribute

    [AttributeUsage(AttributeTargets.Field)]
    public sealed class JniErrorCodeMeaningAttribute : Attribute
    {
        private string mMeaning;

        public JniErrorCodeMeaningAttribute(string meaning)
        {
            mMeaning = meaning;
        }

        public string Meaning { get { return this.mMeaning; } }

        public static string GetMeaning(int code)
        {
            if (!Enum.IsDefined(typeof(JniErrorCode), code))
            {
                return JniResourceManager.Instance.GetString("jniInvalidErrorCode");
            }
            return GetMeaning((JniErrorCode)code);
        }

        public static string GetMeaning(JniErrorCode code)
        {
            JniErrorCodeMeaningAttribute[] atts = (JniErrorCodeMeaningAttribute[])code.GetType().
                GetField(code.ToString()).GetCustomAttributes(
                typeof(JniErrorCodeMeaningAttribute), false);
            if (atts.Length != 1)
            {
                throw new InvalidOperationException(JniResourceManager.Instance.GetString("jniMisconfiguredErrorCode"));
            }
            return JniResourceManager.Instance.GetString(atts[0].Meaning);
        }
    }

    #endregion JniErrorCodeMeaningAttribute

    #region JBooleanConverter

    public sealed class JBooleanConverter
    {
        private JBooleanConverter() { }

        // These are intentionally private, use From/To
        private const byte JNI_FALSE = 0;
        private const byte JNI_TRUE = 1;

        public static bool From(byte @value)
        {   // JNI docs state: A jboolean is an 8-bit unsigned C type that can store 
            // values from 0 to 255. The value 0 corresponds to the constant JNI_FALSE, 
            // and the values from 1 to 255 correspond to JNI_TRUE.
            return (@value != JNI_FALSE);
        }

        public static byte To(bool @value)
        {
            return (@value ? JBooleanConverter.JNI_TRUE : JBooleanConverter.JNI_FALSE);
        }

        public static bool[] FromArray(byte[] values)
        {
            if (values == null)
            {
                return null;
            }
            bool[] boolArray = new bool[values.Length];
            for (int i = 0; i < values.Length; i++)
            {
                boolArray[i] = From(values[i]);
            }
            return boolArray;
        }

        public static byte[] ToArray(bool[] values)
        {
            if (values == null)
            {
                return null;
            }
            byte[] javaBooleans = new byte[values.Length];
            for (int i = 0; i < values.Length; i++)
            {
                javaBooleans[i] = To(values[i]);
            }
            return javaBooleans;
        }
    }

    #endregion JBooleanConverter
}
